﻿using System;


namespace BizElements.BusinessLayer
{
    /// <summary>
    /// Specifies various validation levels.
    /// Business object use this as a hint in their validation methods.
    /// </summary>
    [Serializable]
    public struct ValidationLevel : IComparable
    {
        #region Fields.

        int level;

        #endregion

        #region Predefined levels.

        /// <summary>
        /// Basic database field constraints. Null-checks, data format, minimum and maximum values etc.
        /// </summary>
        /// <remarks>Rules that affect only a single field. Usefull for real-time validation when business object is being edited.</remarks>
        public static ValidationLevel BasicFieldConstraints
        {
            get { return new ValidationLevel(0); }
        }

        /// <summary>
        /// All rules that don't require database access.
        /// Rules that affect more fields. Eg. one of the two fields is required.
        /// </summary>
        /// <remarks>Used when all fields of a business object have been set.</remarks>
        public static ValidationLevel RulesThatDontRequireDatabaseAccess
        {
            get { return new ValidationLevel(1); }
        }

        /// <summary>
        /// All business rules.
        /// </summary>
        /// <remarks>Usually performed before a business object is persisted.</remarks>
        public static ValidationLevel AllBusinessRules
        {
            get { return new ValidationLevel(2); }
        }

        /// <summary>
        /// All busines rules. A lot of database activity.
        /// </summary>
        /// <remarks>Used when client cannot be trusted (3rd party application). Eg. checks all foreign keys.</remarks>
        public static ValidationLevel ThoroughValidation
        {
            get { return new ValidationLevel(3); }
        }

        #endregion

        #region Constructors.

        private ValidationLevel(int level)
        {
            this.level = level;
        }

        #endregion

        #region Methods.

        /// <summary>
        /// Determines whether the two <b>ValidationLevel</b> instances are equal.
        /// </summary>
        /// <param name="obj">Other <b>ValidationLevel</b> instance.</param>
        /// <returns><b>true</b> if the levels are equal; <b>false</b> if not equal or 
        /// if the given object is not an instance of <b>ValidationLevel</b>.</returns>
        public override bool Equals(object obj)
        {
            if (obj is ValidationLevel)
            {
                bool isEqual = (this == (ValidationLevel)obj);
                return isEqual;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Returns the hash code for this instance.
        /// </summary>
        /// <returns>A 32-bit signed integer hash code.</returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        /// <summary>
        /// Determines whether the two <b>ValidationLevel</b> instances are equal.
        /// </summary>
        /// <param name="otherLevel">Other <b>ValidationLevel</b> instance.</param>
        /// <returns><b>true</b> if the levels are equal; <b>false</b> otherwise.</returns>
        public bool Equals(ValidationLevel otherLevel)
        {
            return (this.level == otherLevel.level);
        }

        #endregion

        #region Operators.

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the levels are equal; <b>false</b> otherwise.</returns>
        public static bool operator ==(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level == rhs.level);
        }

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the levels are not equal; <b>false</b> otherwise.</returns>
        public static bool operator !=(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level != rhs.level);
        }

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the left-hand side level is lesser than the right one; <b>false</b> otherwise.</returns>
        public static bool operator <(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level < rhs.level);
        }

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the left-hand side level is equal or lesser than the right one; <b>false</b> otherwise.</returns>
        public static bool operator <=(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level <= rhs.level);
        }

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the left-hand side level is greated than the right one; <b>false</b> otherwise.</returns>
        public static bool operator >(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level > rhs.level);
        }

        /// <summary>
        /// Compares two <b>ValidationLevel</b> instances.
        /// </summary>
        /// <param name="lhs">The first value to be compared.</param>
        /// <param name="rhs">The second value to be compared.</param>
        /// <returns><b>true</b> if the left-hand side level is equal or greater than the right one; <b>false</b> otherwise.</returns>
        public static bool operator >=(ValidationLevel lhs, ValidationLevel rhs)
        {
            return (lhs.level >= rhs.level);
        }

        #endregion

        #region IComparable.

        /// <summary>
        /// Compares the current instance with another <b>ValidationLevel</b> instance.
        /// </summary>
        /// <param name="obj">A <b>ValidationLevel</b> instance to compare with this instance.</param>
        /// <returns>A 32-bit signed integer that indicates the relative order of the objects being compared.</returns>
        public int CompareTo(object obj)
        {
            return CompareTo((ValidationLevel)obj);
        }

        /// <summary>
        /// Compares the current instance with another <b>ValidationLevel</b> instance.
        /// </summary>
        /// <param name="otherLevel">A <b>ValidationLevel</b> instance to compare with this instance.</param>
        /// <returns>A 32-bit signed integer that indicates the relative order of the objects being compared.</returns>
        public int CompareTo(ValidationLevel otherLevel)
        {
            return (this.level.CompareTo(otherLevel.level));
        }

        #endregion
    }
}